#pragma once
#include "SFML\Graphics.hpp"
#include "animSprite.h"
#include "SpriteSheetManager.h"
#include "config.h"
#include "Camera.h"
//#include "Pathfinding.h"

namespace game
{

struct terrain_block
{
	unsigned short int _type;
	unsigned short int _height;
	bool _pathable;
	
	terrain_block(unsigned short int type, unsigned short int z, bool pathable)
	{
		_type = type;
		_height = z;
		_pathable = pathable;
	}
};

class TerrainManager
{
	
	std::vector<std::vector<terrain_block> > _terrain_blocks;
	std::vector<animSprite *> _sprites;
	std::vector<animSprite *> _alphas;
	sf::RenderWindow * _window;
	game::Camera * _camera;
	game::SpriteSheetManager * _sprite_sheet_manager;

public:
	TerrainManager(sf::RenderWindow * window,Camera * camera, game::SpriteSheetManager* ssm)
	{
		_sprite_sheet_manager = ssm;
		_camera = camera;
		_window = window;
	}
	void LoadTerrainSprites(int sprite_sheet_id, int terrain_sprite_ids[], int terrain_sprite_ids_count)
	{
		for (int i = 0; i < terrain_sprite_ids_count; i++)
		{
			unsigned int anim[1] = {terrain_sprite_ids[i]}; // data(
			_sprites.push_back(new animSprite(animSpriteData(sprite_sheet_id,anim,1),_sprite_sheet_manager));
		}
		for (int i = 0; i < 6; i++)	//alphas
		{
			unsigned int anim[1] = {i};
			_alphas.push_back(new animSprite(animSpriteData(1/*alpha ss*/,anim,1),_sprite_sheet_manager));
		}
	}

	void Draw() const
	{	
		if (!_terrain_blocks.empty())
		{
			const int y_size = _terrain_blocks.size();
			for (int j = 0; j < y_size; j++)
			{
				if (_camera->is_range_in_view(false,j * game::GRIDSIZE,0) &&!_terrain_blocks.at(j).empty() )
				{
					const int x_size = _terrain_blocks.at(j).size();

					for (int i = 0; i < x_size; i++)
					{
						int id = _terrain_blocks.at(j).at(i)._type;
						sf::Vector2u pos (game::GRIDSIZE * i + 32,game::GRIDSIZE * j);
						_sprites.at(id)->updatePositionAndDraw(*_window,pos);
					}

				}
			}
		}
	}

	void ClearCurrentMap()
	{
		if (_terrain_blocks.empty()){return;}
		else
		{
			for each (std::vector<terrain_block> tb in _terrain_blocks)
			{
				if (tb.empty()){return;}
				else
				{
					tb.clear();
				}
			}
		_terrain_blocks.clear();
		}
	}
	bool is_grid_pathable(int i, int j)
	{
		return(_terrain_blocks.at(j).at(i)._pathable);
	}

	void MapGenerate(sf::Vector2u start_index, sf::Vector2u end_index)
	{
		/*
		ClearCurrentMap();
		int dx = start_index.x - end_index.x;
		if (dx < 0){dx = -dx;}
		int dy = start_index.y - end_index.y;
		if (dy < 0){dy = -dy;}
		// fill with dirt//
		_terrain_blocks.reserve(dy);
		for (int j = 0; j < dy; j++)
		{
			std::vector<terrain_block> y_blocks;	y_blocks.reserve(dx);
			for (int i = 0; i < dx; i++)
			{
				y_blocks.push_back(terrain_block(0,0,true));
			}
			_terrain_blocks.push_back(y_blocks);
		}
		int[32][
		game::PathFinder::GetPath(start_index.x,start_index.y,end_index.x,end_index.y,

		*/
	}

	void LoadRandomMap(int max_x, int max_y, int variety, int max_height = 1)
	{
		ClearCurrentMap();
		_terrain_blocks.reserve(max_y);
		for (int j = 0; j < max_y; j++)
		{
			std::vector<terrain_block> y_blocks;	y_blocks.reserve(max_x);
			for (int i = 0; i < max_x; i++)
			{
				unsigned int id = rand() % variety;
				y_blocks.push_back(
					terrain_block(id,		//ground types
					rand()%max_height,	//get z
					id != 0));								//pathable

				std::string d = "";
				if (id!=0){d = ".";}else{d = "0";}
				std::cout << d <<" ";// std::cout
			}
			std::cout << std::endl;
			_terrain_blocks.push_back(y_blocks);
		}
		_terrain_blocks.at(3).at(3)._type = 4;
	}
	~TerrainManager()
	{
		ClearCurrentMap();
		const int size = _sprites.size();
		for (int i = 0; i < size; i++)	//enable after refactoring
		{
			delete _sprites[i];
		}
	}
};

}